package ch.bfh.abch.rems.receiver.tinkerforge;

import java.io.IOException;
import java.io.StringReader;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;

import org.apache.log4j.Logger;

import ch.bfh.abch.rems.REMSMulticastController;
import ch.bfh.abch.rems.interfaces.tinkerforge.TFClusterNodeAverageDataPersiser;
import ch.bfh.abch.rems.receiver.MulticastReceiver;
import ch.bfh.abch.rems.sender.tinkerforge.TFClusterNodeAverage;

import com.google.gson.Gson;
import com.google.gson.stream.JsonReader;

public class TFMulticastReceiver extends MulticastReceiver {

    private static Logger logger = Logger.getLogger("play");

    private TFClusterNodeAverageDataPersiser averageDataPersiser;
    private MulticastSocket multicastSocket;
    private TFMulticastReceiverThread receiverThread;

    public TFMulticastReceiver(TFClusterNodeAverageDataPersiser persiser, String multicastAdress, int port) {
        this.averageDataPersiser = persiser;
        try {
            this.receiverThread = new TFMulticastReceiverThread();
            this.multicastSocket = new MulticastSocket(port);
            this.multicastSocket.joinGroup(InetAddress.getByName(multicastAdress));
        } catch (UnknownHostException e) {
            logger.error("UnknownHostException: " + e.getMessage());
        } catch (IOException e) {
            logger.error("IOException: " + e.getMessage());
        }
    }

    public synchronized void startReceiving() {
        logger.debug("ReceiverThread is NULL"+(receiverThread==null));
        if (!receiverThread.isAlive()) {
            logger.debug("ReceiverThread is not alive");
            receiverThread.start();
        }else{
            logger.debug("ReceiverThread is alive, do nothing");
            
        }
           
    }

    private class TFMulticastReceiverThread extends Thread {

        @Override
        public void run() {
            logger.debug("Start ReceiverThread");
            byte[] buffer = new byte[REMSMulticastController.DEFAULT_BYTE_ARRAY_LENGTH];
            DatagramPacket datagramPacket = new DatagramPacket(buffer, buffer.length);
            try {
                while (true) {
                    logger.info("Waiting for CNAMulticast...");
                    multicastSocket.receive(datagramPacket);
                    logger.debug("Received multicast");
                    saveClusterNodeAverage(new String(datagramPacket.getData()));
                }
            } catch (IOException e) {
                logger.error("IOException: " + e.getMessage());
            }
        }

        private synchronized void saveClusterNodeAverage(String multicastData) {
            logger.debug("RECEIVER: " + multicastData);
            Gson gson = new Gson();
            JsonReader reader = new JsonReader(new StringReader(multicastData));
            reader.setLenient(true);
            TFClusterNodeAverage cna = gson.fromJson(reader, TFClusterNodeAverage.class);
            logger.info("Save: " + cna.toString());
            averageDataPersiser.saveClusterNodeAverage(cna.getValue(), cna.getClusterNodeID(), cna.getSensorType());
        }
    }
}
